/******************************************************************************
 * 
 * Announce: CSharpKit, Basic algorithms, components and definitions.
 *           Copyright (C) ShenYongchen.
 *           All rights reserved.
 *   Author: 申永辰.郑州 (shenyczz@163.com)
 *  WebSite: http://gitee.com/shenyczz/csharp_csk
 *
 * THIS CODE IS LICENSED UNDER THE MIT LICENSE (MIT).
 * THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
 * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
 * IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
 * PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
 * 
******************************************************************************/

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace CSharpKit.Convertions
{
    /// <summary>
    /// KConverter - 工具包转换器
    /// </summary>
    public sealed class KConverter
    {
        KConverter() { }
        /// <summary>
        /// 缓冲区大小
        /// </summary>
        private const int BUFFER_SIZE = 1024;


        public static ArrayConverter ArrayConverter => CSharpKit.Convertions.ArrayConverter.Instance;
        public static BytesConverter BytesConverter => CSharpKit.Convertions.BytesConverter.Instance;
        public static Base64Converter Base64Converter => CSharpKit.Convertions.Base64Converter.Instance;
        public static Data2ImageConverter Data2ImageConverter => CSharpKit.Convertions.Data2ImageConverter.Instance;
        public static IntPtrConverter IntPtrConverter => CSharpKit.Convertions.IntPtrConverter.Instance;
        public static StrtuctConverter StrtuctConverter => CSharpKit.Convertions.StrtuctConverter.Instance;




        /// <summary>
        /// 把经过的秒数转换位UTC日期
        /// </summary>
        /// <param name="totalSeconds">UTC计数的秒数，从1970-01-01 00:00:00 开始计数</param>
        /// <returns></returns>
        public static DateTime UTCFromSeconds(Int32 totalSeconds)
        {
            return DateTime.Parse("1970-01-01 00:00:00").AddSeconds(totalSeconds);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static Int32 UTCToSeconds(DateTime dateTime)
        {
            TimeSpan timeSpan = DateTime.UtcNow.Subtract(DateTime.Parse("1970-01-01 00:00:00"));
            Int32 seconds = Convert.ToInt32(timeSpan.TotalSeconds);
            return seconds;
        }


        /// <summary>
        /// 字节转换到字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        [Obsolete("不再使用", true)]
        public static String Bytes2String(Byte[] bytes)
        {
            var result = string.Empty;

            try
            {
                for (int i = 0; i < bytes?.Length; i++)
                {
                    if (bytes[i] == 0)
                    {
                        for (int pos = i; pos < bytes.Length; pos++)
                        {
                            bytes[pos] = 0;
                        }
                        break;
                    }
                }

#if NET31 || NET50 || NET60
                // 'GB18030' is not a supported encoding name.
                // For information on defining a custom encoding, 
                // see the documentation for the Encoding.RegisterProvider method. (Parameter 'name')
                System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
#endif
                result = Encoding.GetEncoding("GB18030").GetString(bytes).Trim(new char[] { '\0' });
            }
            catch (Exception ex)
            {
                string errMsg = ex.Message;
            }


            return result;
        }

        /// <summary>
        /// 字符串转换到字节
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static Byte[] String2Bytes(String str)
        {
#if NET31 || NET50 || NET60
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
#endif
            return Encoding.GetEncoding("GB18030").GetBytes(str);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rawdatas"></param>
        /// <returns></returns>
        [Obsolete("不再使用", true)]
        public static T Bytes2Struct<T>(byte[] rawdatas)
        {
            Type anytype = typeof(T);
            int rawsize = Marshal.SizeOf(anytype);
            if (rawsize > rawdatas.Length)
                return default(T);

            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawdatas, 0, buffer, rawsize);
            object retobj = Marshal.PtrToStructure(buffer, anytype);
            Marshal.FreeHGlobal(buffer);

            return (T)retobj;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [Obsolete("不再使用", true)]
        public static byte[] Struct2Bytes(object obj)
        {
            int rawsize = Marshal.SizeOf(obj);
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.StructureToPtr(obj, buffer, false);
            byte[] rawdatas = new byte[rawsize];
            Marshal.Copy(buffer, rawdatas, 0, rawsize);
            Marshal.FreeHGlobal(buffer);
            return rawdatas;
        }


        /// <summary>
        /// 对象转换到指针
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [Obsolete("不再使用", true)]
        public static IntPtr ToIntPtr(Object obj)
        {
            IntPtr pObject = IntPtr.Zero;

            try
            {
                GCHandle hObject = GCHandle.Alloc(obj, GCHandleType.Pinned);
                pObject = hObject.AddrOfPinnedObject();
                if (hObject.IsAllocated) hObject.Free();
            }
            catch (Exception)
            {
                // no body
            }

            return pObject;
        }

        // public static T ToStruct<T>(Object obj)
        // {
        //     return (T)Marshal.PtrToStructure(ToIntPtr(obj), typeof(T));
        // }




        /// <summary>
        /// 指针转换到字符串
        /// </summary>
        /// <param name="p"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        [Obsolete("不再使用", true)]
        public static string IntPtr2String(IntPtr p, int len = 0)
        {
            string str_value = "";

            try
            {
                int actual_len = len == 0 ? BUFFER_SIZE : len;
                byte[] uc_temp = new byte[actual_len];
                Marshal.Copy(p, uc_temp, 0, actual_len);
                str_value = Bytes2String(uc_temp);
            }
            catch (Exception)
            {
                str_value = "";
            }

            return str_value;
        }







        //}}@@@
    }


}
